// Copyright (c) 2007-2009 Google Inc.
// Copyright (c) 2006-2007 Jaiku Ltd.
// Copyright (c) 2002-2006 Mika Raento and Renaud Petit
//
// This software is licensed at your choice under either 1 or 2 below.
//
// 1. MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// 2. Gnu General Public license 2.0
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
//
// This file is part of the JaikuEngine mobile client.

#include "cn_datacounter.h"
#include "cbbsession.h"
#include "badesca.h"

class CDataCounterReaderImpl : public CDataCounterReader,
	public MContextBase, public MBBObserver {
public:
	MDataCounterObserver& iObserver;
	CDataCounterReaderImpl(MDataCounterObserver& aObserver) :
	  iObserver(aObserver) { }
	TInt iTotalRead, iTotalSent;
	CBBSubSession* iBBSubSession;
	void ConstructL() {
		iBBSubSession=BBSession()->CreateSubSessionL(this);
		iBBSubSession->AddNotificationL(KReceivedDataCounterTuple, ETrue);
		iBBSubSession->AddNotificationL(KSentDataCounterTuple, ETrue);

		iConnections=new (ELeave) CDesCArraySeg(4);
	}
	~CDataCounterReaderImpl() {
		delete iBBSubSession;
		delete iConnections;
		iReadCounts.Close();
		iSentCounts.Close();
	}

	CDesCArraySeg*	iConnections;
	RArray<TInt>	iReadCounts, iSentCounts;

	TInt GetConnectionIdxL(const TDesC& aConnection) {
		for (int i=0; i<iConnections->Count(); i++) {
			if (iConnections->MdcaPoint(i).Compare(aConnection)==0) return i;
		}
		User::LeaveIfError(iReadCounts.Append(0));
		User::LeaveIfError(iSentCounts.Append(0));
		iConnections->AppendL(aConnection);
		return iConnections->Count()-1;
	}
	virtual void NewValueL(TUint aId, 
		const TTupleName& aName, const TDesC& aSubName, 
		const TComponentName& aComponentName, const MBBData* aData)
	{
		const TBBInt* i=bb_cast<TBBInt>(aData);
		if (!i) return;
		TInt idx=GetConnectionIdxL(aSubName);
		if (aName==KReceivedDataCounterTuple) {
			iTotalRead-=iReadCounts[idx];
			iTotalRead+=(*i)();
			iReadCounts[idx]=(*i)();
		} else {
			iTotalSent-=iSentCounts[idx];
			iTotalSent+=(*i)();
			iSentCounts[idx]=(*i)();
		}
		iObserver.CountersChanged(iTotalRead, iTotalSent);
	}
	virtual void DeletedL(const TTupleName& aName, const TDesC& aSubName)
	{
	}

};

EXPORT_C CDataCounterReader* CDataCounterReader::NewL(MDataCounterObserver& aObserver)
{
	auto_ptr<CDataCounterReaderImpl> ret(
		new (ELeave) CDataCounterReaderImpl(aObserver) );
	ret->ConstructL();
	return ret.release();
}
